#include <cstddef>
#include <iostream>
#include <memory>
using namespace std;

template <typename T>  T* yaddressof(T& p) {
    return reinterpret_cast<T*>(
        &const_cast<char&>(reinterpret_cast<const volatile char&>(p)));
}

namespace Yt {

template <typename Tp, std::size_t Num> struct array {
    typedef Tp value_type;
    typedef value_type& reference;
    typedef const value_type& const_reference;
    typedef value_type* pointer;
    typedef const value_type* const_pointer;
    typedef value_type* iterator;
    typedef const value_type* const_iterator;
    typedef std::size_t size_type;
    typedef std::ptrdiff_t difference_type;

    value_type instance[Num ? Num : 1];

    iterator begin() { return iterator(yaddressof(instance[0])); }
    const_iterator begin() const {
        return const_iterator(yaddressof(instance[0]));
    }

    iterator end() { return iterator(yaddressof(instance[Num])); }
    const_iterator end() const {
        return const_iterator(yaddressof(instance[Num]));
    }

    size_type size() const { return Num; }

    size_type max_size() const { return Num; }

    bool empty() const { return size() == 0; }

    reference operator[](size_type index) { return instance[index]; }

    const_reference operator[](size_type index) const {
        return instance[index];
    }

    reference at(size_type index) { return instance[index]; }

    const_reference at(size_type index) const { return instance[index]; }

    reference front() { return *begin(); }
    reference back() { return Num ? *(end() - 1) : *end(); }
    value_type* data() { return yaddressof(instance[0]); }
};

} // namespace Yt